package com.ceba.test.modules.sign.logicService;

import com.ceba.test.modules.sign.helper.SignHelper;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import com.ceba.base.enums.PdfOResultEnum;
import com.ceba.base.enums.SealTypeEnum;
import com.ceba.base.helper.LoggerHelper;
import com.ceba.base.sign.enums.ErrSign;
import com.ceba.base.utils.PDFUtils;
import com.ceba.base.utils.PdfSignUtils;
import com.ceba.base.utils.ToPdfUtils;
import com.ceba.base.utils.pdf.PdfOResult;
import com.ceba.base.web.response.IResult;
import com.ceba.cebautils.DateUtil;
import com.ceba.cebautils.IDUtils;
import com.ceba.test.base.config.LogicPathUtil;
import com.ceba.test.base.constants.CustomStampConstants;
import com.ceba.test.base.enums.*;
import com.ceba.test.base.utils.StringUtil;
import com.ceba.test.modules.admin.entity.*;
import com.ceba.test.modules.admin.helper.GStampHelper;
import com.ceba.test.modules.admin.service.WaterPageNumberService;
import com.ceba.test.modules.log.helper.RestLogHelper;
import com.ceba.test.modules.sign.helper.SignInServerHelper;
import com.ceba.test.modules.storage.logicService.StorageFileCacheManage;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.parser.*;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ceba.cebacer.KeyLoaderType;
import com.ceba.forpdf.pdf.PdfTools;
import com.ceba.service.bean.CMessage;
import com.ceba.service.bean.StatusCodeType;
import com.ceba.test.base.configs.CebaConfig;
import com.ceba.test.base.configs.CebaPathUtil;
import com.ceba.test.base.configs.ServerSignConfig;
import com.ceba.test.base.constants.TextConstants;
import com.ceba.test.base.sign.helper.CheckSignHelper;
import com.ceba.test.base.helper.SystemHelper;
import com.ceba.test.base.language.ResourceUtils;
import com.ceba.test.modules.admin.helper.QRCodeHelper;
import com.ceba.test.modules.admin.service.GReportMergeService;
import com.ceba.test.modules.admin.service.InterfaceSignService;
import com.ceba.test.modules.admin.service.StampService;
import com.ceba.test.modules.filemanage.dto.WebSignParam;
import com.ceba.test.modules.filemanage.service.FileManagerService;
import com.ceba.test.modules.log.helper.OpLogHelper;
import com.ceba.test.modules.sign.service.SignService;
import com.ceba.test.modules.statistic.entity.ReportSign;
import com.ceba.test.modules.usermanage.entity.UUser;
import com.ceba.test.modules.usermanage.service.UserService;

import abc.ID;
import abc.util.FileHelper;
import abc.util.FileUtils;

public class SignLogicService {
	private static Logger logger = LoggerFactory.getLogger(SignLogicService.class);

	private GReportMergeService gReportMergeService;
	private FileManagerService fileManagerService;
	private StampService stampService;
	private SignService signService;
	private InterfaceSignService interfaceSignService;
	private UserService userService;

	private WaterPageNumberService waterPageNumberService;
	
	public InterfaceSignService getInterfaceSignService() {
		return interfaceSignService;
	}

	public void setInterfaceSignService(InterfaceSignService interfaceSignService) {
		this.interfaceSignService = interfaceSignService;
	}

	public SignService getSignService() {
		return signService;
	}

	public void setSignService(SignService signService) {
		this.signService = signService;
	}
	
	public StampService getStampService() {
		return stampService;
	}

	public void setStampService(StampService stampService) {
		this.stampService = stampService;
	}

	public GReportMergeService getGReportMergeService() {
		return gReportMergeService;
	}

	public void setGReportMergeService(GReportMergeService gReportMergeService) {
		this.gReportMergeService = gReportMergeService;
	}

	public FileManagerService getFileManagerService() {
		return fileManagerService;
	}

	public void setFileManagerService(FileManagerService fileManagerService) {
		this.fileManagerService = fileManagerService;
	}


	public UserService getUserService() {
		return userService;
	}

	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	/**
	 * 测试签名是否正常
	 * 
	 * @return 1路径有问题，2、签名不被许可，正常则返回签名PDF路径
	 * @throws Exception
	 */
	public String testSign() throws Exception {
		String path = LogicPathUtil.getPhysicalTemplateFolder(StorageFileCacheManage.getSystemUseAddressId()) + "test.pdf";// 测试的地址
		String outPath = LogicPathUtil.getPhysicalTempFolder(StorageFileCacheManage.getSystemUseAddressId())  + "test.pdf";// 保存的地址
		if (!FileHelper.exists(path)) {
			return "-1";
		}
		JSONObject checkSign = CheckSignHelper.checkCanSign();
		if (!(ErrSign.ERR_0.getCode()+"").equals(checkSign.getString("status"))) {
			return checkSign.getString("status");
		}
		IResult iResult = new IResult(true);
		if (FileHelper.exists(path)) {
			GStamp gs = new GStamp();
			String imgPath = CebaPathUtil.getVisualtransPic();
			gs.setFilePath(imgPath);
			gs.setSealType(SealTypeEnum.DRAFTING_POSTION_STAMP_FLAG.getType());
			
			List<GStamp> gStamps = new ArrayList<GStamp>();
			gStamps.add(gs);
			
			//获取统计的参数
			UUser user = userService.getUserById(TextConstants.adminId);
	        ReportSign  parm = new ReportSign(1,user.getName(),EditionTypeEnum.BE.getType());
	        //测试签名不计算签名份数
	        parm.setTestSign(true);
			parm.setQrCodeFileId(IDUtils.getGuid());
			//控制签名时关键字没匹配上是否报错 true-不报错 false-报错
			iResult.set("isNoErrorNotNoramlMatchKey", "true");
	        signPdf( path, outPath, gStamps, iResult,parm);
			
			if (iResult.getResult()) {
				outPath = iResult.getString("filePath");
				return URLEncoder.encode(outPath, "utf-8");
			}
		}

		return "";

	}


	
	/**
	 * 对一个文件进行签名
	 * 
	 * @param filePath
	 *            需要签名的文件路径，不能为空
	 * @return 返回空则签章不成功，否则为签章文件路径
	 * @throws Exception
	 */
	public void sign(String filePath, WebSignParam webSignParam,IResult result) throws Exception {
		String fileName = webSignParam.getFileName();
		//String savePath = LogicPathUtil.getTodayPhysicalSignFmFolder(StorageFileCacheManage.getSystemUseAddressId())+ StringUtil.indexRepxStr(fileName.substring(0, fileName.lastIndexOf(".")), "[\u4e00-\u9fa5a-zA-Z0-9]") + ".pdf";// 保存的地址
		String savePath = LogicPathUtil.getTodayPhysicalSignFmFolder(StorageFileCacheManage.getSystemUseAddressId())+ fileName.substring(0, fileName.lastIndexOf(".")) + ".pdf";// 保存的地址
		//判断签名服务器是否有隐形签名
		boolean isNoSign = false;
		GStamp gStamp =  stampService.queryDigitalStampCerNO();
		if(gStamp==null){
			result.setResult(false);
			result.set("code", StatusCodeType.CODE_100.getCode());
			//请配置数字签名(加密）签/章
			result.setMessage(ResourceUtils.getMessage("SYSTEM_PLEASE_ADD_NUMBER_SEAL_THREE"));
			return ;
		}
		try {
			List<GStamp> gStamps = new ArrayList<GStamp>();
			if(webSignParam.getSignStampIds() !=null && webSignParam.getSignStampIds().size() >0){
				for(String gsId :webSignParam.getSignStampIds()){
					
					if(gsId.equals(CustomStampConstants.NO_SIGN) && SystemHelper.canChooseServerSignFlow()){
						//isNoSign = true;
					}
					//获取签/章信息
					GStamp gs = stampService.getStampById(gsId);
					//表示做隐形签名
					if(gs == null){
						gs = new GStamp();
						gs.setMatchName("");
						gs.setStamp_x("0");
						gs.setStamp_y("0");
						gs.setImgHeight("1");
						gs.setImgWidth("1");
						//默认给第一条数据中的证书编号
						gs.setCerNo(gStamp.getCerNo());
						gs.setKeyName(gStamp.getKeyName());
						gs.setEncodeSignType(gStamp.getEncodeSignType());
						gs.setSealType(SealTypeEnum.DRAFTING_POSTION_STAMP_FLAG.getType());
						gs.setFilePath(CebaPathUtil.getVisualtransPic());
					} else {
						logger.info("sign: privateKeyName=" + gs.getKeyName());
					}
					gStamps.add(gs);
				}
			}
			
			if(isNoSign){
				result.setResult(false);
				result.set("code", StatusCodeType.CODE_100.getCode());
				result.setMessage( ResourceUtils.getMessage("SERVER_SIGN_NO_CERNO_ONE"));
				return ;
			}
			  //获取统计的参数
	        ReportSign  parm = new ReportSign(1,webSignParam.getUserName(),EditionTypeEnum.BE.getType());
			parm.setFileId(webSignParam.getFileId());
			// 可复制
			parm.setAllowCopy(webSignParam.getAllowCopy());
            parm.setQrCodeFileId(webSignParam.getQrCodeFileId());
			signPdf(filePath, savePath, gStamps,result,parm);

		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			e.printStackTrace();
		}

	}
	

	/**
	 * 签名方法--前台签名页面调用
	 * 
	 * @return
	 * @throws Exception
	 */
	public  void signPdf(String inputPath, String savePath, List<GStamp> gStamps,IResult result, ReportSign  parm) throws Exception {
		if (SystemHelper.canChooseServerSignFlow()) {
			logger.info("签名服务器方式signPdf:" + ServerSignConfig.SERVER_SIGN_FLOW);
			signPdfWithServer(inputPath, savePath, gStamps,result,parm);
			return;
		} else {
			logger.info("插key方式signPdf:" + ServerSignConfig.SERVER_SIGN_FLOW);
		}
		String fileName = FileUtils.getFileName(savePath, false);
		String userName = parm !=null?parm.getCreateUserName():"";
		String imgPath  = "";
		CMessage cm = null;
		if(gStamps!=null && gStamps.size() >0){
			ISign[] iSignss  = new ISign[gStamps.size()];
			for(int i = 0 ; i < gStamps.size() ; i++){
				GStamp gs = gStamps.get(i);
				imgPath  =LogicPathUtil.getSystemUploadPath(gs.getStorageAddressId())+ gs.getFilePath();
				String errCode = CheckSignHelper.checkHasSpecialNode();
				if (!(ErrSign.ERR_0.getCode() + "").equals(errCode)) {
					result.setResult(false);
					result.setMessage(ResourceUtils.getMessage(ErrSign.getLanguageFlag(Integer.valueOf(errCode))));
					return ;
				}
				
				if (keyMatchNeedShowError(inputPath, savePath, new JSONObject(gs), result)) {
					return;
				}
				ISign iSign = new ISign();
				iSign.setKeyType(KeyLoaderType.TYPE_CEBA_KEY);
				iSign = GStamp.packToI_Signs(gs,iSign);

				//添加可复制属性
				iSign.setAllowPdfContentCopy(parm.getAllowCopy());
				iSign.setStampPath(imgPath);
				iSignss[i] = iSign;
			}
			cm = SignInServerHelper.signPdf(inputPath, savePath, iSignss,parm);
			if (StatusCodeType.CODE_200.getCode().equals(cm.getStatusCode())||
				StatusCodeType.CODE_0.getCode().equals(cm.getStatusCode())) {
				OpLogHelper.signOperationLogs(userName+ "于"
						+ DateUtil.getNowTime(DateUtil.YYYY_MM_DD_HH_MM_SS) + "对报告" + fileName+ "进行签名 ");
				result.set("filePath", savePath);
				return;
			}
		}
		result.setResult(false);
		if (null != cm) {
			result.setMessage(cm.getMessage());
		} else {
			result.setMessage(ResourceUtils.getMessage(PdfOResultEnum.PDF_EXCEPTIONS.getResourceName()));
		}
		OpLogHelper.signOperationLogs(userName + "于"
				+ DateUtil.getNowTime(DateUtil.YYYY_MM_DD_HH_MM_SS) + "对报告" + fileName + "签名签名失败");
		return ;
	}


	/*
	 * 获取证书剩余天数，少于30天时显示
	 */
	public String getValideDayOfLicense() {
		String validay = signService.getValideDayOfLicense();
		if(!StringUtil.isEmptyString(validay) && !validay.equals("over")){
			return ResourceUtils.getMessage("REPORT_YOUR_DIGITAL_CERTIFICATE")+validay+ResourceUtils.getMessage("REPORT_AFTER_EXPIRATION_APPLY");
		}else if(validay.equals("over")){
			return ResourceUtils.getMessage("REPORT_YOUR_DIGITAL_CERTIFICATE_APPLY_TIME");
		}
		return "";
	}


	/**
	 * 在FM中对文件进行签名
	 * 
	 * @param pdfFilePath
	 *            pdf文件路径,
	 * @return 签名后的物理路径，
	 */
	public IResult signFileInFM(String pdfFilePath,WebSignParam webSignParam,IResult result,String qrcodeFileId) {
		String tempPath ="";
		try {
			if (!FileHelper.exists(pdfFilePath)) {
				result.setResult(false);
				result.setMessage(ResourceUtils.getMessage("SYSTEM_FILE_NOT_EXIST"));
				return result;
			}
			// 是否是PDF文件
			if (!FileHelper.getFileExtName(pdfFilePath).toLowerCase().equals("pdf")) {
				result.setResult(false);
				result.setMessage(ResourceUtils.getMessage("SIGN_PDF_FORMAT_ERROR"));
				return result;
			}
			//已经签名的文档不可继续签名;服务器签名不需判断文档是否签名
			boolean hasSign = PdfSignUtils.checkFileHasSign(pdfFilePath);
			if (hasSign && !SystemHelper.canChooseServerSignFlow()) {
				result.setResult(false);
				result.setResultCode(Integer.parseInt(PdfOResultEnum.PDF_HAS_SIGNATURE.getCode()));
				result.setMessage(ResourceUtils.getMessage(PdfOResultEnum.PDF_HAS_SIGNATURE.getResourceName()));
				return result;
			}

			//服务器签名不需要判断文档是否签名,顾已经签名的文档，再次签名时不走下述插入操作
			if (!hasSign){
				// 1--插入水印
				if(!StringUtil.isEmptyString(webSignParam.getWaterMarkId())){
					insertWaterStampPages(pdfFilePath,webSignParam ,result); ;
					if(!result.getResult()){
						return result;
					}else{
						pdfFilePath = result.getString("filePath");
					}
				}
				
				// 2--合并
				if(!StringUtil.isEmptyString(webSignParam.getGFileMergeId())){
					mergeFile(pdfFilePath,webSignParam ,result);
					if(!result.getResult()){
						return result;
					}else{
						pdfFilePath = result.getString("filePath");
					}
				}
				
				// 3--骑缝章(获取骑缝章规则)
				if(!StringUtil.isEmptyString(webSignParam.getQfStampId())){
					insertQifeng(pdfFilePath,webSignParam ,result);
					if(!result.getResult()){
						return result;
					}else{
						pdfFilePath = result.getString("filePath");
					}
				}
				
				// 4--插入其他印章
				if(webSignParam.getOtherStampIds() !=null && webSignParam.getOtherStampIds().size() >0){
					tempPath = LogicPathUtil.getPhysicalTempFolderByUserId(StorageFileCacheManage.getSystemUseAddressId(),webSignParam.getUserId())+ID.getGuid() + ".pdf";
					insertOtherSealStamps(pdfFilePath, tempPath, webSignParam.getOtherStampIds(), result);
					if(!result.getResult()){
						return result;
					}else{
						pdfFilePath = result.getString("filePath");
					}
				}		
				// 5--是否插入二维码
				if(SystemHelper.canUseQR() && webSignParam.getAllowAddQr() == 0){
					tempPath = LogicPathUtil.getPhysicalTempFolder(StorageFileCacheManage.getSystemUseAddressId()) + ID.getGuid() + ".pdf";// 保存的地址
					if (keyMatchNeedShowError(pdfFilePath, tempPath, QRCodeHelper.getQrJson(), result)) {
						result.setMessage(ResourceUtils.getMessage("SYSTEM_QR_CODE")+
								ResourceUtils.getMessage(ErrorCode.CODE_33.resourceDesc));
						return result;
					}
					pdfFilePath = QRCodeHelper.needInsertQRImage(pdfFilePath, tempPath, qrcodeFileId);
					result.set("filePath",pdfFilePath);
				}
			}

			//判断是否为 客户端签名
			// 6--插入数字签名章--都用数字章
			if(BeKyeEnum.PUBLIC_CER_KEY.getCode().equals(CebaConfig.BE_KEY_FLAG)){
				if(webSignParam.getSignStampIds() !=null && webSignParam.getSignStampIds().size() >0){
                    webSignParam.setQrCodeFileId(qrcodeFileId);
					sign(pdfFilePath, webSignParam,result);
				} else {
					// 不需要数字签名的文件，同样保存到sign目录下。
					// 否则，temp目录下的文件会在第二天被删除。
					pdfFilePath = saveTmpFileToSignDir(pdfFilePath, webSignParam);
					result.set("filePath",pdfFilePath);
				}
			}else{
				// 不需要数字签名的文件，同样保存到sign目录下。
				// 否则，temp目录下的文件会在第二天被删除。
				pdfFilePath = saveTmpFileToSignDir(pdfFilePath, webSignParam);
				result.set("filePath",pdfFilePath);
			}
		} catch (Exception e) {
			LoggerHelper.error(logger, e, "");
		}

		return result;
	}

	private String saveTmpFileToSignDir(String pdfFilePath, WebSignParam webSignParam) throws IOException {
		String fileName = webSignParam.getFileName();
		String savePath = LogicPathUtil.getTodayPhysicalSignFmFolder(StorageFileCacheManage.getSystemUseAddressId())+ fileName.substring(0, fileName.lastIndexOf(".")) + ".pdf";
		FileHelper.copyFile(pdfFilePath, savePath);
		pdfFilePath = savePath;
		return pdfFilePath;
	}

	/**
	 * 添加一个数字证书签名记录
	 * 
	 *            签名的文件Id
	 * @return
	 */
	public Boolean addSignRecord(ReportSign  parm)
			throws Exception {
		return signService.addSignRecord(parm);
	}

	/**
	 * 根据二维码上传状，获取签名文件
	 * @param qrFileUploadFlag
	 * @return
	 * @throws Exception
	 */
	public List<ReportSign> getReportSign(QrFileUploadFlagEnum qrFileUploadFlag) throws Exception {
		return signService.getReportSign(qrFileUploadFlag);
	}

	/**
	 * 更新签名报告的二维码上传状态
	 * @param id
	 * @param qrFileUploadFlag
	 * @return
	 * @throws Exception
	 */
	public boolean updateReportSign(String id, QrFileUploadFlagEnum qrFileUploadFlag)  throws Exception {
		return signService.updateReportSign(id, qrFileUploadFlag);
	}

	/**
	 * 可视化签名接口--对外---该方法仅支持单签
	 * @param pdfPath
	 * @param outPath
	 * @param signFlag
	 *            true 就是 又盖章 又签名 false只盖章
	 * @param gsMaps
	 */
	public JSONObject signVisualStampFacade(String pdfPath, String outPath, boolean signFlag,
			Map<String, List<GStamp>> gsMaps, ISign iSign,ReportSign  parm,String storageId) {

		// 日志打印
		String interfaceName = "signVisualStampFacade";
		RestLogHelper.fnStartDebug(Thread.currentThread().getName(), interfaceName);
		RestLogHelper.fnPrintParamDebug(Thread.currentThread().getName(), interfaceName,
				new JSONObject(iSign).toString(), pdfPath);

		JSONObject result = new JSONObject();
		if (gsMaps == null) {
			result.put("code", "100");
			result.put("message", ResourceUtils.getMessage("BASE_NO_SIGNATURE_OPTION"));
			RestLogHelper.fnEndDebug(Thread.currentThread().getName(), interfaceName, result.toString());
			return result;
		} else {
			try {
				boolean isSm2Sign = PdfSignUtils.checkFileHasSM2Signed(pdfPath);
				boolean isRsaSign = PdfSignUtils.checkFileHasRSASigned(pdfPath);

				// 若是KEY模式，判断是否能够签名
				if (iSign.getKeyType() == KeyLoaderType.TYPE_CEBA_KEY && signFlag) {
					JSONObject checkSign = CheckSignHelper.checkCanSign();
					if (!(ErrSign.ERR_0.getCode()+"").equals(checkSign.getString("status"))) {
						result.put("code", checkSign.getString("status"));
						result.put("message", checkSign.getString("message"));
						RestLogHelper.fnEndDebug(Thread.currentThread().getName(), interfaceName, result.toString());
						return result;
					}
				}

				ISign[] iSigns = null;
				// 创建ISign集合
				List<ISign> iSignsAll = new ArrayList<ISign>();
				String tempPath="";
				List<GStamp> enterStamps = new ArrayList<GStamp>();// 报告章
				List<GStamp> qfStamps = new ArrayList<GStamp>();// 骑缝章
				List<GStamp> signStamp = new ArrayList<GStamp>(); // 签名章
				List<GStamp> dateStamp = new ArrayList<GStamp>(); // 日期印章
				List<GStamp> examineStamp = new ArrayList<GStamp>(); // 审批章

				// 获取pdf的页码数
				// PdfFile pdfFile = ToPdfUtils.getPdfFile(pdfPath);
				// Map<Integer, PdfPage> mapPages= pdfFile.getPdfPages();

				// 用来处理骑缝章
				tempPath = LogicPathUtil.getPhysicalTempFolder(storageId) + ID.getGuid() + ".pdf";
				for (Map.Entry<String, List<GStamp>> entry : gsMaps.entrySet()) {
					// 报告章盖数字章
					if (gsMaps.get(entry.getKey()) != null) {
						// if(entry.getKey().equals(StampTypeEnum.ENTERPRISE_COR_STAMP_FLAG.getType())){
						if (gsMaps.get(entry.getKey()).size() > 0 && gsMaps.get(entry.getKey()).get(0).getCorFlag()
								.equals(StampTypeEnum.DIGITAL_STAMP_FLAG.getType())) {

							enterStamps = gsMaps.get(entry.getKey());
							// 将印章转化
							if (enterStamps.size() > 0) {
								for (GStamp gStamp : enterStamps) {
									ISign iSignTemp = new ISign();
									// 防止后台接口没有设置关键 且 页面只有一个章的时 盖透明章
									gStamp.setMatchName("ss");
									ISign.copyISignToISign(iSignTemp, iSign);
									SignInServerHelper.copyGSToISign(gStamp, iSignTemp, pdfPath,parm.getEditionType());
									iSignTemp.setPdfHasRSASigned(isRsaSign);
									iSignTemp.setPdfHasSM2Signed(isSm2Sign);
									iSignsAll.add(iSignTemp);
								}
							}

						}

						// 手写签名章
						if (gsMaps.get(entry.getKey()).size() > 0 && gsMaps.get(entry.getKey()).get(0).getCorFlag()
								.equals(StampTypeEnum.USER_COR_STAMP_FLAG.getType())) {
							signStamp = gsMaps.get(entry.getKey());
							if (signStamp.size() > 0) {
								for (GStamp gStamp : signStamp) {
									ISign iSignTemp = new ISign();
									gStamp.setMatchName("ss");
									ISign.copyISignToISign(iSignTemp, iSign);
									SignInServerHelper.copyGSToISign(gStamp, iSignTemp, pdfPath,parm.getEditionType());
									iSignTemp.setPdfHasRSASigned(isRsaSign);
									iSignTemp.setPdfHasSM2Signed(isSm2Sign);
									iSignsAll.add(iSignTemp);
								}
							}
						}

						// 审批章
						if (gsMaps.get(entry.getKey()).size() > 0 && gsMaps.get(entry.getKey()).get(0).getCorFlag()
								.equals(StampTypeEnum.USER_COR_EXAMINE_STAMP_FLAG.getType())) {
							examineStamp = gsMaps.get(entry.getKey());
							if (examineStamp.size() > 0) {
								for (GStamp gStamp : examineStamp) {
									ISign iSignTemp = new ISign();
									gStamp.setMatchName("ss");
									ISign.copyISignToISign(iSignTemp, iSign);
									SignInServerHelper.copyGSToISign(gStamp, iSignTemp, pdfPath,parm.getEditionType());
									iSignTemp.setPdfHasRSASigned(isRsaSign);
									iSignTemp.setPdfHasSM2Signed(isSm2Sign);
									iSignsAll.add(iSignTemp);
								}
							}
						}

						if (gsMaps.get(entry.getKey()).size() > 0 && gsMaps.get(entry.getKey()).get(0).getCorFlag()
								.equals(StampTypeEnum.CREDIENTAL_COR_DATE_STAMP_FLAG.getType())) {
							dateStamp = gsMaps.get(entry.getKey());
							if (dateStamp.size() > 0) {
								for (GStamp gStamp : dateStamp) {
									ISign iSignTemp = new ISign();
									gStamp.setMatchName("ss");
									ISign.copyISignToISign(iSignTemp, iSign);
									SignInServerHelper.copyGSToISign(gStamp, iSignTemp, pdfPath,parm.getEditionType());
									iSignTemp.setPdfHasRSASigned(isRsaSign);
									iSignTemp.setPdfHasSM2Signed(isSm2Sign);
									iSignsAll.add(iSignTemp);
								}
							}
						}

						// 骑缝章特需处理
						if (gsMaps.get(entry.getKey()).size() > 0 && gsMaps.get(entry.getKey()).get(0).getCorFlag()
								.equals(StampTypeEnum.QIFENG_COR_STAMP_FLAG.getType())) {
							qfStamps = gsMaps.get(entry.getKey());
							for (GStamp gStamp : qfStamps) {
								JSONObject object = new JSONObject();
								object.put("imgWidth", gStamp.getImgWidth());
								object.put("imgHeight", gStamp.getImgHeight());
								object.put("positionRate", gStamp.getPositionRate());
								JSONArray list = PDFUtils.getQFStampsByRule(pdfPath, tempPath,
										LogicPathUtil.getFilePathByVirtualPath(storageId,gStamp.getFilePath()), object);
								for (int index = 0; index < list.length(); index++) {
									GStamp _stamp = new GStamp();
									object = list.getJSONObject(index);
									_stamp.setImgWidth(object.getLong("imgWidth") + "");
									_stamp.setImgHeight(object.getLong("imgHeight") + "");
									String virtualPath = object.getString("filePath");
									_stamp.setFilePath("images" + virtualPath.split("images")[1]);
									_stamp.setStamp_x(object.getString("stampX"));
									_stamp.setStamp_y(object.getString("stampY"));
									_stamp.setStampPage(object.getString("stampPage"));
									_stamp.setId(ID.getGuid());
									_stamp.setCorFlag(StampTypeEnum.QIFENG_COR_STAMP_FLAG.getType());

									// _stampList.add(_stamp);
									ISign iSignTemp = new ISign();
									ISign.copyISignToISign(iSignTemp, iSign);
									SignInServerHelper.copyGSToISign(_stamp, iSignTemp, pdfPath,parm.getEditionType());
									iSignTemp.setPdfHasRSASigned(isRsaSign);
									iSignTemp.setPdfHasSM2Signed(isSm2Sign);
									iSignsAll.add(iSignTemp);
								}
							}
						}
					}

				}

				// 将集合中的iSign 封装到iSigns集合中
				if (iSignsAll != null && iSignsAll.size() > 0) {
					iSigns = new ISign[iSignsAll.size()];
					for (int i = 0; i < iSignsAll.size(); i++) {
						iSigns[i] = iSignsAll.get(i);
					}
				}

				if(signFlag) {
					CMessage cm = SignInServerHelper.signPdf(pdfPath, outPath, iSigns,parm);

					if (StatusCodeType.CODE_0.getCode().equals(cm.getStatusCode())) {
						cm.setStatusCode(StatusCodeType.CODE_200.getCode());
					}
					result.put("code", cm.getStatusCode());
				//	result.put("message", cm.getMessage());
					if(StatusCodeType.CODE_2000.getCode().equals(cm.getStatusCode())){
						result.put("message", ResourceUtils.getMessage("SERVER_KEY_NOT_SUPPORT_MULTIPLE_SIGN"));
					}else{
						result.put("message", ResourceUtils.getMessage(PdfOResultEnum.PDF_EXCEPTIONS.getResourceName()));
					}
					result.put("outPath", outPath);
					RestLogHelper.fnEndDebug(Thread.currentThread().getName(), interfaceName, result.toString());
					return result;
				} else {
					result.put("code", StatusCodeType.CODE_200.getCode());
					result.put("outPath", pdfPath);
				}
			} catch (Exception e) {
				result.put("code", "100");
				result.put("message", ResourceUtils.getMessage("BASE_DOCUMENT_SIGNATURE_FAILURE"));
			}
		}
		RestLogHelper.fnEndDebug(Thread.currentThread().getName(), interfaceName, result.toString());
		return result;
	}

	/**
	 * 基础版--采用签名服务器方式
	 * 
	 * @param inputPath
	 * @param savePath
	 */
	public static void signPdfWithServer(String inputPath, String savePath, List<GStamp> gStamps,IResult result,ReportSign  parm) {
		try {
			String fileName = FileUtils.getFileName(savePath, false);
			String userName = parm !=null?parm.getCreateUserName():"";
			if(gStamps!=null && gStamps.size() >0){
				ISign[] iSignss  = new ISign[gStamps.size()];
				for(int i = 0 ; i < gStamps.size() ; i++){
					GStamp gs = gStamps.get(i);
					ISign iSign = new ISign();
					iSign.setKeyType(SystemHelper.getServerType());
					iSign.setEncodeSignType(gs.getEncodeSignType());
					if(StringUtil.isEmptyString(gs.getCerNo())){
						result.setResult(false);
						result.set("code", StatusCodeType.CODE_100.getCode());
						result.setMessage( ResourceUtils.getMessage("SERVER_SIGN_NO_CERNO"));
						return ;
					}
					if (keyMatchNeedShowError(inputPath, savePath, new JSONObject(gs), result)) {
						return;
					}
					iSign.setCerNo(gs.getCerNo());
					iSign.setPrivateKeyName(gs.getKeyName());
					iSign.setServerIp(ServerSignConfig.signServerIp);
					String port = ServerSignConfig.serverSignPort;
					if(!StringUtil.isEmptyString(port)){
						iSign.setServerPort(Integer.valueOf(ServerSignConfig.serverSignPort));
					}
					iSign.setServerUrlSuffix(ServerSignConfig.serverSignSuffix);
					iSign.setCertificationLevel(SystemHelper.getCertificateLevel());
					iSign.setPositive(0);
					iSign.setMoveType(1);
					iSign.setFatherType(ServerSignConfig.serverFatherType);
					iSign.setSignType(Integer.valueOf(gs.getSealType()));
					// 添加可复制属性
					iSign.setAllowPdfContentCopy(parm.getAllowCopy());
					SignInServerHelper.copyGSToISign(gs, iSign, inputPath,parm.getEditionType());
					iSignss[i] = iSign;
					OpLogHelper.signOperationLogs( userName + "于"
							+ DateUtil.getNowTime(DateUtil.YYYY_MM_DD_HH_MM_SS) + "对" + fileName + "进行签名 证书编号为:"
							+ gs.getCerNo() + " 签名类型为:" + (gs.getEncodeSignType() == 1 ? "RSA" : "SM2(国密)"));
				}
				CMessage cm = SignInServerHelper.signPdf(inputPath, savePath, iSignss,parm);

				if (StatusCodeType.CODE_0.getCode().equals(cm.getStatusCode())
						|| StatusCodeType.CODE_200.getCode().equals(cm.getStatusCode())) {
						OpLogHelper.signOperationLogs(userName + "于"
								+ DateUtil.getNowTime(DateUtil.YYYY_MM_DD_HH_MM_SS) + "对报告" + fileName+ "进行签名成功 ");
						result.set("filePath", savePath);
						return;
				}
				result.setResult(false);
				result.set("code", cm.getStatusCode());
				if(cm.getStatusCode().equals("100")){
					result.setMessage(ResourceUtils.getMessage("MODULES_FAILURE_SIGNATURE"));
				}else if(cm.getStatusCode().equals("106")){
					result.setMessage(ResourceUtils.getMessage("SERVER_SIGN_NO_CERNO"));
				}else{
					result.setMessage(cm.getMessage());
				}
				ResourceUtils.getMessage(PdfOResultEnum.PDF_EXCEPTIONS.getResourceName());
				OpLogHelper.signOperationLogs(userName + "于"
						+ DateUtil.getNowTime(DateUtil.YYYY_MM_DD_HH_MM_SS) + "对报告" + fileName + "签名签名失败");
			}
		} catch (Exception e) {
			result.setResult(false);
			result.set("code", StatusCodeType.CODE_100.getCode());
			result.setMessage( ResourceUtils.getMessage("BASE_DOCUMENT_SIGNATURE_FAILURE"));
			LoggerHelper.error(logger, e, "");
		}
	}

	/**
	 * 获取所有签名报告个数
	 * 
	 * @return
	 */
	public long getAllSignReports() throws Exception {
		return signService.getAllSignReports();
	}
	
	/**
	 * 获取所有签名报告个数
	 * 
	 * @return
	 */
	public long getCusUserAllSignReports(String userId,int editionType) throws Exception {
		return signService.getCusUserAllSignReports(userId,editionType);
	}

	/**
	 * 获取今年所有签名报告个数
	 * 
	 * @return
	 */
	public long getYearSignReports() throws Exception {
		return signService.getYearSignReports();
	}

	/**
	 * 获取所有签名附件个数
	 * 
	 * @return
	 */
	public long getAllSignOReports() throws Exception {
		return signService.getAllSignOReports();
	}

	/**
	 * 获取今年所有签名附件个数
	 * 
	 * @return
	 */
	public long getYearSignOReports() throws Exception {
		return signService.getYearSignOReports();
	}

	/**
	 * 获取前一天所有签名报告个数
	 * 
	 * @return
	 */
	public long getLastDayReportSign() throws Exception {
		return signService.getLastDayReportSign();
	}

	/**
	 * 获取前一天所有签名附件个数
	 * 
	 * @return
	 */
	public long getLastDayAttachSign() {
		return signService.getLastDayAttachSign();
	}

	/**
	 * 插入骑缝章
	 * @param pdfFilePath
	 * @param webSignParam
	 * @param result
	 * @throws Exception 
	 */
	public void insertQifeng(String pdfFilePath, WebSignParam webSignParam, IResult result) throws Exception {
		// 欧陆一页纸pdf，不签骑缝章
		if (false == CebaConfig.IS_QIFENG_IN_ONE_PAGE_PDF && 1 == PdfTools.getPdfPages(pdfFilePath)) {
			result.set("filePath", pdfFilePath);
			result.setResult(true);
			return;
		}

		QfRule customResource = interfaceSignService.getQiFengRuleById(webSignParam.getQfStampId());
		if(customResource == null){
			result.setResult(false);
			result.setMessage(ResourceUtils.getMessage("QIFENG_ID_NOT_EXSIT"));
		}else{
			String outPath = LogicPathUtil.getPhysicalTempFolderByUserId(StorageFileCacheManage.getSystemUseAddressId(),webSignParam.getUserId())+ID.getGuid() + ".pdf";
			JSONObject object = new JSONObject(customResource);
			object.put("filePath", LogicPathUtil.getSystemUploadPath(customResource.getStorageAddressId()) + customResource.getFilePath());
			object.put("insertFlag", "1");
			object.put("saveSplit", "2");
			object.put("splitWeight", SystemHelper.getQfSplitWeight());
			getFirstPageNumByKeyword(pdfFilePath, webSignParam, object);
			int code = PDFUtils.insertQFStampByRule(pdfFilePath, outPath, object);
			if(code == 0){
				result.set("filePath", outPath);
				result.setResult(true);
			}else{
				result.setResult(false);
				result.setMessage(ResourceUtils.getMessage("QIFENG_INSERT_WRONG"));
			}
		}
	}

	private void getFirstPageNumByKeyword(String pdfFilePath, WebSignParam webSignParam, JSONObject object) {
		String startPageOfQifeng = webSignParam.getStartPageOfQifeng();
		String endPageOfQifeng = webSignParam.getEndPageOfQifeng();

		getFirstPageNumByKeyword(pdfFilePath, object, "start", startPageOfQifeng);
		getFirstPageNumByKeyword(pdfFilePath, object, "end", endPageOfQifeng);
	}

	private void getFirstPageNumByKeyword(String pdfFilePath,
										  JSONObject object,
										  String qifengConfigKey,
										  String pageOfQifeng) {
		if (!StringUtils.isEmpty(pageOfQifeng)) {
			if (StringUtil.isPositiveInteger(pageOfQifeng)) {
				object.put(qifengConfigKey, pageOfQifeng);
			} else {
				List<Integer> result = getKeywordPages(pdfFilePath, pageOfQifeng);

				//获取第一个关键字的位置
				if (result != null && result.size() >= 1) {
					object.put(qifengConfigKey, result.get(0).toString());
				}
			}
		}
	}

	private List<Integer> getKeywordPages(String pdfFile, String keyword) {
		List<Integer> resultPageNumbers = new ArrayList<>();
		try {
			PdfReader reader = new PdfReader(pdfFile);
			int pageNumbs = reader.getNumberOfPages();
			for (int i=1; i<pageNumbs+1; ++i) {
				if (PdfTextExtractor.getTextFromPage(reader, i).indexOf(keyword) >= 0) {
					resultPageNumbers.add(i);
				}
			}
		} catch (IOException e) {
			logger.error(String.format("根据关键字查找页数时，文件读取失败失败：pdfFile=%s, keyword=%s", pdfFile, keyword), e);
		}

		return resultPageNumbers;
	}

	/**
	 * 合并首尾页
	 * @param pdfFilePath
	 * @param webSignParam
	 * @param result
	 * @throws Exception 
	 */
	public void mergeFile(String pdfFilePath, WebSignParam webSignParam, IResult result) throws Exception {
		GReportMerge rm = gReportMergeService.getReportMergeById(webSignParam.getGFileMergeId());
		if(rm == null){
			result.setResult(false);
			result.setMessage(ResourceUtils.getMessage("MERGE_ID_NOT_EXSIT"));
		}else{
			String outPath = LogicPathUtil.getPhysicalTempFolderByUserId(StorageFileCacheManage.getSystemUseAddressId(),webSignParam.getUserId())+ID.getGuid() + ".pdf";
			boolean flag = insertReportMerge(pdfFilePath,outPath,webSignParam.getGFileMergeId());
			if(!flag){
				result.setResult(false);
				result.setMessage(ResourceUtils.getMessage("MERGE_FILE_WRONG"));
			}else{
				result.set("filePath", outPath);
			}
		}
	}
	
	/**
	 * 插入封面与尾页
	 * 
	 * @param filePath
	 *            要签名的文档路径
	 * @param reportMergeId
	 *            报告封面与尾页配置id
	 * @return
	 * @throws Exception
	 */
	private boolean insertReportMerge(String filePath, String outPath,String reportMergeId) throws Exception {
		String coverFilePath = gReportMergeService.getFilePathByMergeId(reportMergeId, "COVER_FILE_PATH");
		String footerFilePath = gReportMergeService.getFilePathByMergeId(reportMergeId, "FOOTER_FILE_PATH");
		
		ArrayList<String> files = new ArrayList<>();
		if (!StringUtil.isEmptyString(coverFilePath)) {
			files.add(coverFilePath);
		}
		files.add(filePath);
		if (!StringUtil.isEmptyString(footerFilePath)) {
			files.add(footerFilePath);
		}
		if (ToPdfUtils.mergePdfFiles(files, outPath)) {
			filePath = outPath;
			return true;
		} 
		return false;
	}

	/**
	 * 插入水印
	 * @return
	 * @throws Exception
	 */
	public void insertWaterStampPages(String pdfFilePath,WebSignParam webSignParam,IResult result) throws Exception {
		String[] arry;
		arry = webSignParam.getWaterMarkId().split(",");
		int count=0;
		String error="";
		if (arry != null && arry.length > 0) {
			for(String waterId : arry){
				GStamp waterStamp = stampService.getWatermark(waterId, StampTypeEnum.WATERMARK_COR_STAMP_FLAG.getType());
				if(waterStamp == null){
					result.setResult(false);
					result.setMessage(ResourceUtils.getMessage("SIGN_WATERMARK_NOT_EXSIT_ERROR"));
				}else {
					String outPath = LogicPathUtil.getPhysicalTempFolderByUserId(StorageFileCacheManage.getSystemUseAddressId(), webSignParam.getUserId()) + ID.getGuid() + ".pdf";// 保存的地址
					String watermarkPath =LogicPathUtil.getSystemUploadPath(waterStamp.getStorageAddressId()) + waterStamp.getFilePath();
					JSONArray jsonArray = getWaterPages(waterStamp,watermarkPath,pdfFilePath);
					//(String outPath,String filePath,JSONArray stamps)
					String resultPath = PDFUtils.insertQianWaterByPages(outPath, pdfFilePath, jsonArray);
					if(resultPath.equals(outPath)){
						//插入水印成功
						pdfFilePath = resultPath;
					}else{
						//插入失败
						count++;
						error+="水印"+waterStamp.getCorStampName()+"盖章失败。";
					}
				}
			}
			result.set("filePath", pdfFilePath);
		}
	}

	public JSONArray getWaterPages(GStamp waterStamp,String watermarkPath,String pdfFilePath){
		JSONArray jsonArray = new JSONArray();
		try{
			//获取水印的页码
			GWaterPageNumber gWaterPageNumber = waterPageNumberService.queryWaterPageNumberByStampId(waterStamp.getId());
			if(gWaterPageNumber!=null && gWaterPageNumber.getId()!=null){
				if(gWaterPageNumber.getRadioFlag().equals(WaterPageNumberEnum.WATER_PAGE_ALL.getCode())){
					//全部页码
					JSONObject jsonObject = new JSONObject();
					jsonObject.put("filePath", watermarkPath );
					jsonObject.put("stampPage", "all" );
					jsonArray.put(jsonObject);
					return jsonArray;
				}else if(gWaterPageNumber.getRadioFlag().equals(WaterPageNumberEnum.WATER_PAGE_OTHER.getCode())){
					//其他
					String selectFlag = gWaterPageNumber.getSelectFlag();
					int pageCount = PdfTools.getPdfPages(pdfFilePath);
					if(selectFlag.equals(WaterPageNumberSelectEnum.WATER_FIRST_END_PAGE.getCode())){
						//首尾页
						JSONObject jsonObject1 = new JSONObject();
						JSONObject jsonObject2 = new JSONObject();
						jsonObject1.put("filePath", watermarkPath );
						jsonObject1.put("stampPage", "1" );
						jsonObject2.put("filePath", watermarkPath );
						jsonObject2.put("stampPage", pageCount+"" );
						jsonArray.put(jsonObject1);
						jsonArray.put(jsonObject2);
						return jsonArray;
					}else if(selectFlag.equals(WaterPageNumberSelectEnum.WATER_SELECT_PAGE.getCode())){
						//选择页码
						String selectPageNumber = gWaterPageNumber.getSelectPageNumber();
						String pageNumbers[] = selectPageNumber.split(",");
						if(pageNumbers.length>0){
							for(String number : pageNumbers){
								JSONObject jsonObject = new JSONObject();
								int num = Integer.valueOf(number);
								//只有小于或者等于总页数的页码才添加
								if(num<pageCount || num == pageCount){
									jsonObject.put("filePath", watermarkPath );
									jsonObject.put("stampPage", number );
									jsonArray.put(jsonObject);
								}
							}
						}
						return jsonArray;
					}else if(selectFlag.equals(WaterPageNumberSelectEnum.WATER_REMOVE_FIRST_END_PAGE.getCode())){
						//除去首尾页
						for(int i=1;i<pageCount-1;i++){
							JSONObject jsonObject = new JSONObject();
							jsonObject.put("filePath", watermarkPath );
							jsonObject.put("stampPage", (i+1)+"" );
							jsonArray.put(jsonObject);
						}
						return jsonArray;
					}else if(selectFlag.equals(WaterPageNumberSelectEnum.WATER_REMOVE_PAGES.getCode())){
						String selectPageNumber = gWaterPageNumber.getSelectPageNumber();
						String pageNumbers[] = selectPageNumber.split(",");
						if(pageNumbers.length>0){
							//将所有页码转换成数组，再转换集合，删除不想盖章的页面
							String[] pageCounts = new String[pageCount];
							for(int i=0;i<pageCount;i++){
								pageCounts[i] = (i+1)+"";
							}
							List<String> pageCountList = new ArrayList<>(Arrays.asList(pageCounts));
							List<String> removePagetList = new ArrayList<>(Arrays.asList(pageNumbers));
							pageCountList.removeAll(removePagetList);
							if(pageCountList.size()>0){
								for(String number : pageCountList){
									JSONObject jsonObject = new JSONObject();
									jsonObject.put("filePath", watermarkPath );
									jsonObject.put("stampPage", number);
									jsonArray.put(jsonObject);
								}
							}
							return jsonArray;
						}else{
							for(int i=1;i<pageCount;i++){
								JSONObject jsonObject = new JSONObject();
								jsonObject.put("filePath", watermarkPath );
								jsonObject.put("stampPage", i+"" );
								jsonArray.put(jsonObject);
							}
						}
					}

				}
			}

		}catch (Exception e){
			LoggerHelper.error(e,"");
		}
		return jsonArray;
	}
	
	
	/**
	 * 插入其他签章的方法
	 * 
	 */
	public void insertOtherSealStamps(String inputPath, String outPath, List<String> otherStampIds,IResult result) {
		try {	
			String stampPage = "";
			if(otherStampIds !=null && otherStampIds.size() >0){
				for(int stampCount = 0 ; stampCount < otherStampIds.size() ; stampCount++){
                    List<Integer> pageList = new ArrayList<>();
					boolean allFlag = false;
					String otherStampId = otherStampIds.get(stampCount);
					GStamp crStamp = stampService.getStampById(otherStampId);
					if (crStamp != null) {
						if (keyMatchNeedShowError(inputPath, outPath, new JSONObject(crStamp), result)) {
							return;
						}
						String tempPath = LogicPathUtil.getPhysicalTempFolder(StorageFileCacheManage.getSystemUseAddressId()) + ID.getGuid() + ".pdf";// 保存的地址
						if( stampCount == otherStampIds.size() -1 ){
							tempPath = outPath;
						}
						//判断采用关键字定位还是拖拽定位
						if(crStamp.getSealType().equals(SealTypeEnum.KEYWORD_STAMP_FLAG.getType())){
							String imgPath = getOtherSealImagePath(crStamp);
							crStamp.setFilePath(imgPath);
							boolean flag = PDFUtils.insertImageByMatchName(inputPath,tempPath,new JSONObject(crStamp));
							if (flag) {
								if( stampCount == otherStampIds.size() -1 ){
									result.set("filePath", tempPath);
									return;
								}else{
									inputPath = tempPath;
								}
							}else{
								if (keyMatchNeedShowOtherStampError(result, inputPath, stampCount, otherStampIds)) {
									return;
								}
							}
						}else{
							//拖拽定位
							stampPage = crStamp.getStampPage();
							if(stampPage.equalsIgnoreCase("all")){
								allFlag = true;
							}else{
								//1个关键字插入多页
								String page[] = stampPage.split(",");
								int pages = PdfTools.getPdfPages(inputPath);
								if (page != null) {
									if (page.length >= 1) {
										for (int i = 0; i < page.length; i++) {
											if (Integer.parseInt(page[i]) <= pages) {
												pageList.add(Integer.valueOf(page[i]));
											}
										}
									} else {
										//没有页数，默认第一页
										pageList.add(Integer.valueOf("1"));
									}
								} else {
									pageList.add(Integer.valueOf("1"));
								}
							}
							String imgPath = getOtherSealImagePath(crStamp);
							JSONObject object = new JSONObject(crStamp);
							object.put("filePath",imgPath);
							object.put("allFlag",allFlag);
							boolean itppbxy = PDFUtils.insertToPagesPositionByXY(tempPath, inputPath, object, pageList);
							if (itppbxy) {
								if( stampCount == otherStampIds.size() -1 ){
									result.set("filePath", tempPath);
									return ;
								}else{
									inputPath = tempPath;
								}
							}else{
								result.setResult(false);
								result.setMessage(ResourceUtils.getMessage("OTHER_STAMP_INSERT_WRONG"));
								return;
							}
						}
						
					}
				}
			}
		} catch (Exception e) {
			LoggerHelper.error(logger, e, "");
		}
		result.setResult(false);
		result.setMessage(ResourceUtils.getMessage("OTHER_STAMP_INSERT_WRONG"));
	}

	/**
	 * 插入其他签章的方法
	 *
	 */
	public void insertOtherSealStampsWithCustomDate(String inputPath, String outPath, List<String> otherStampIds, Map<String, String> customDateToContent, IResult result) {
		try {
			String stampPage = "";
			if(otherStampIds !=null && otherStampIds.size() >0){
				for(int stampCount = 0 ; stampCount < otherStampIds.size() ; stampCount++){
					List<Integer> pageList = new ArrayList<>();
					boolean allFlag = false;
					String otherStampId = otherStampIds.get(stampCount);
					GStamp crStamp = stampService.getStampById(otherStampId);
					if (crStamp != null) {
						if (null != customDateToContent && customDateToContent.containsKey(otherStampId)) {
							crStamp.setClassString(customDateToContent.get(otherStampId));
						}

						if (keyMatchNeedShowError(inputPath, outPath, new JSONObject(crStamp), result)) {
							return;
						}
						String tempPath = LogicPathUtil.getPhysicalTempFolder(StorageFileCacheManage.getSystemUseAddressId()) + ID.getGuid() + ".pdf";// 保存的地址
						if( stampCount == otherStampIds.size() -1 ){
							tempPath = outPath;
						}
						//判断采用关键字定位还是拖拽定位
						if(crStamp.getSealType().equals(SealTypeEnum.KEYWORD_STAMP_FLAG.getType())){
							String imgPath = getOtherSealImagePath(crStamp);
							crStamp.setFilePath(imgPath);
							boolean flag = PDFUtils.insertImageByMatchName(inputPath,tempPath,new JSONObject(crStamp));
							if (flag) {
								if( stampCount == otherStampIds.size() -1 ){
									result.set("filePath", tempPath);
									return;
								}else{
									inputPath = tempPath;
								}
							}else{
								if (keyMatchNeedShowOtherStampError(result, inputPath, stampCount, otherStampIds)) {
									return;
								}
							}
						}else{

							//拖拽定位
							stampPage = crStamp.getStampPage();
							if(stampPage.equalsIgnoreCase("all")){
								allFlag = true;
							}else{
								//1个关键字插入多页
								String page[] = stampPage.split(",");
								int pages = PdfTools.getPdfPages(inputPath);
								if (page != null) {
									if (page.length >= 1) {
										for (int i = 0; i < page.length; i++) {
											if (Integer.parseInt(page[i]) <= pages) {
												pageList.add(Integer.valueOf(page[i]));
											}
										}
									} else {
										//没有页数，默认第一页
										pageList.add(Integer.valueOf("1"));
									}
								} else {
									pageList.add(Integer.valueOf("1"));
								}
							}
							String imgPath = getOtherSealImagePath(crStamp);
							JSONObject object = new JSONObject(crStamp);
							object.put("filePath",imgPath);
							object.put("allFlag",allFlag);
							boolean itppbxy = PDFUtils.insertToPagesPositionByXY(tempPath, inputPath, object, pageList);
							if (itppbxy) {
								if( stampCount == otherStampIds.size() -1 ){
									result.set("filePath", tempPath);
									return ;
								}else{
									inputPath = tempPath;
								}
							}else{
								result.setResult(false);
								result.setMessage(ResourceUtils.getMessage("OTHER_STAMP_INSERT_WRONG"));
								return;
							}
						}

					}
				}
			}
		} catch (Exception e) {
			LoggerHelper.error(logger, e, "");
		}
		result.setResult(false);
		result.setMessage(ResourceUtils.getMessage("OTHER_STAMP_INSERT_WRONG"));
	}

	/**
	 * 获取其他签章的图片地址
	 * @param crStamp
	 * @return
	 */
	private String getOtherSealImagePath(GStamp crStamp) {
		//获取自定义日期章
		if (StampTypeEnum.CUSTOM_COR_DATE_STAMP_FLAG.getType().equalsIgnoreCase(crStamp.getCorFlag())) {
			try {
				GStamp data= GStampHelper.searchDateStampWithCustomDate(CebaConfig.ANDMIN_USER_ID,CebaConfig.CUSTOM_DATE_FORMAT, crStamp.getClassString());
				return LogicPathUtil.getBrowserPathToAbsolutelyPath(data.getFilePath());
			} catch (Exception e) {
				logger.error(e.getMessage());
				e.printStackTrace();
			}
		}
		return LogicPathUtil.getSystemUploadPath(crStamp.getStorageAddressId()) + crStamp.getFilePath();
	}


	/**
	 * 数字签章插入单个关键字
	 * 先查找关键字
	 * 再定位盖章
	 */
	public void insertSignSealStamps(String inputPath, String outPath, List<String> signStampIds,IResult result) {
		String stampPage = "";
		boolean allFlag = false;
		List<Integer> pageList = new ArrayList<>();
		try {	
		if(signStampIds !=null && signStampIds.size() >0){
			for(int stampCount = 0 ; stampCount < signStampIds.size() ; stampCount++){
				String signStampId = signStampIds.get(stampCount);
				GStamp crStamp = stampService.getStampById(signStampId);
				if (crStamp != null) {
					String tempPath = LogicPathUtil.getPhysicalTempFolder(StorageFileCacheManage.getSystemUseAddressId()) + ID.getGuid() + ".pdf";// 保存的地址
					if( stampCount == signStampIds.size() -1 ){
						tempPath = outPath;
					}
					//判断采用关键字定位还是拖拽定位
					if(crStamp.getSealType().equals(SealTypeEnum.KEYWORD_STAMP_FLAG.getType())){
						String imgPath = LogicPathUtil.getSystemUploadPath(crStamp.getStorageAddressId()) + crStamp.getFilePath();
						crStamp.setFilePath(imgPath);
						
						//获取第一个关键字的位置
						JSONArray arr =PDFUtils.getArraysOfPagesByMatchName(tempPath,inputPath,crStamp.getMatchName(),
								Float.parseFloat(crStamp.getImgWidth()) ,Float.parseFloat(crStamp.getImgHeight()));
						
						if(arr!=null){
							arr.getJSONObject(0).put("filePath", crStamp.getFilePath());
							tempPath = LogicPathUtil.getPhysicalTempFolder(StorageFileCacheManage.getSystemUseAddressId()) + ID.getGuid() + ".pdf";// 保存的地址
							boolean flag = PDFUtils.insertImageByMatchNameXY(inputPath,tempPath,arr.getJSONObject(0));
							if(flag){
								inputPath = tempPath;
							}
						}
						tempPath=inputPath;
						if( stampCount == signStampIds.size() -1 ){
							result.set("filePath", tempPath);
							return;
						}else{
							inputPath = tempPath;
						}
					}else{
						//拖拽定位
						stampPage = crStamp.getStampPage();
						if(!StringUtil.isEmptyString(stampPage)){
							pageList.add(Integer.valueOf(stampPage));
						}else{
							pageList.add(Integer.valueOf("1"));
						}
						
						String imgPath =LogicPathUtil.getSystemUploadPath(crStamp.getStorageAddressId()) + crStamp.getFilePath();
						JSONObject object = new JSONObject(crStamp);
						object.put("filePath",imgPath);
						object.put("allFlag",allFlag);
						boolean itppbxy = PDFUtils.insertToPagesPositionByXY(tempPath, inputPath, object, pageList);
						if (itppbxy) {
							if( stampCount == signStampIds.size() -1 ){
								result.set("filePath", tempPath);
								return ;
							}else{
								inputPath = tempPath;
							}
						}else{
							result.setResult(false);
							result.setMessage(ResourceUtils.getMessage("SIGN_STAMP_INSERT_WRONG"));
							return;
						}
					}
					
				}
			}
		  }
		} catch (Exception e) {
			LoggerHelper.error(logger, e, ResourceUtils.getMessage("SIGN_STAMP_INSERT_WRONG"));
	}
		result.setResult(false);
		result.setMessage(ResourceUtils.getMessage("SIGN_STAMP_INSERT_WRONG"));
	}

	public WaterPageNumberService getWaterPageNumberService() {
		return waterPageNumberService;
	}

	public void setWaterPageNumberService(WaterPageNumberService waterPageNumberService) {
		this.waterPageNumberService = waterPageNumberService;
	}

	public  void signTest(int count) throws  Exception{
		signService.signTest(count);
	}

	public int queryFileCount(int count) throws  Exception{
		return signService.queryFileCount(count);
	}

	/**
	 * 关键字匹配不到是否返回错误码
	 * @param inputPath
	 * @param outPath
	 * @param
	 * @return
	 */
	public static boolean qrKeyMatchNeedShowError(String inputPath, String outPath, JSONObject crJsonStamp, boolean isNoErrorNotNoramlMatchKey) {
		//true-不报错 false-报错
		if (isNoErrorNotNoramlMatchKey) {
			return false;
		}
		PdfOResult pdfOReslut = PDFUtils.getOtherPdfOResultCanInsertImage(inputPath,outPath,crJsonStamp);
		if(!PdfOResultEnum.SUCCESS.getCode().equals(pdfOReslut.getPdfCode())){
			return true;
		}
		return false;
	}

	/**
	 * 关键字匹配不到是否返回错误码
	 * @param inputPath
	 * @param outPath
	 * @param result
	 * @return true-报错
	 */
	public static boolean keyMatchNeedShowError(String inputPath, String outPath, JSONObject crJsonStamp, IResult result) {
		//true-不报错 false-报错
		boolean isNoErrorNotNoramlMatchKey = result.getString("isNoErrorNotNoramlMatchKey") == "true" ? true:false;
		if (isNoErrorNotNoramlMatchKey) {
			return false;
		}
		PdfOResult pdfOReslut = PDFUtils.getOtherPdfOResultCanInsertImage(inputPath,outPath,crJsonStamp);
		if(!PdfOResultEnum.SUCCESS.getCode().equals(pdfOReslut.getPdfCode())){
			result.setResult(false);
			result.setResultCode(Integer.parseInt(pdfOReslut.getPdfCode()));
			result.setMessage(ResourceUtils.getMessage(pdfOReslut.getResourceName(),
					new Object[]{pdfOReslut.getIndexPage()}));
			return true;
		}
		return false;
	}

	/**
	 * 关键字匹配不到，是否返回错误码
	 * @param result
	 * @return
	 */
	private boolean keyMatchNeedShowOtherStampError(IResult result, String inputPath, int stampCount, List<String> otherStampIds) {
		//true-不报错 false-报错
		boolean isNoErrorNotNoramlMatchKey = result.getString("isNoErrorNotNoramlMatchKey") == "true" ? true:false;
		if (!isNoErrorNotNoramlMatchKey) {
			result.setResult(false);
			result.setMessage(ResourceUtils.getMessage("OTHER_STAMP_INSERT_WRONG"));
			return false;
		}
		if( stampCount == otherStampIds.size() -1 ){
			result.set("filePath", inputPath);
		}
		return true;
	}

}
